From: tsteven4 Date: Sun, 10 Mar 2019 15:10:36 +0000 (-0600) Subject: convert ozi io to QTextStream (#315) X-Git-Tag: archive/raspbian/1.10.0+ds-2+rpi1~1^2~12^2~8^2~23 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success/%22http:/www.example.com/cgi/success?a=commitdiff_plain;h=2f652ec9a560586238e0bdf702151e4ef9c56175;p=gpsbabel.git convert ozi io to QTextStream (#315) * convert ozi io to QTextStream. and add an option to set the codec. default the codec to windows-1252, which matches historic usage but not recent behavior. fix a memory leak, csv_lineparse needs to die. fix a mistranslation with QString::arg. * enhance ozi test for routes and tracks. * eliminate csv_lineparse in ozi. * eliminate obsolete commented code in ozi. * update encoding comments for ozi. * add doc for ozi codec option. --- diff --git a/ozi.cc b/ozi.cc index ef9a147fe..8c3015cb9 100644 --- a/ozi.cc +++ b/ozi.cc @@ -20,30 +20,63 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + Reference: + https://www.oziexplorer4.com/eng/help/fileformats.html + + According to the OZI Explorer developer: + "There is no specified character set, it defaults to whatever 8 bit + character set "Windows" defaults to - normally CP-1252 but can vary + depending on Windows regional settings." + + According to the reference, for some text fields: + "comma's not allowed in text fields, character 209 can be used instead + and a comma will be substituted." + This could work for windows-1252, but not for utf-8. + We don't support any special handling for character 209. + */ +#include // for tolower +#include // for lround +#include // for atoi + +#include // for QByteArray +#include // for operator==, QChar +#include // for QCharRef +#include // for QFile +#include // for QFileInfo +#include // for QFlags +#include // for operator|, QIODevice::WriteOnly, QIODevice::ReadOnly, QIODevice, QIODevice::OpenModeFlag +#include // for QString +#include // for QStringList +#include // for QTextCodec +#include // for QTextStream, operator<<, qSetRealNumberPrecision, QTextStream::FixedNotation +#include // for CaseInsensitive +#include // for qPrintable + #include "defs.h" -#include "cet_util.h" -#include "csv_util.h" -#include "jeeps/gpsmath.h" -#include -#include -#include /* for floor */ -#include -#include +#include "csv_util.h" // for csv_stringclean +#include "jeeps/gpsmath.h" // for GPS_Math_Known_Datum_To_WGS84_M +#include "src/core/datetime.h" // for DateTime +#include "src/core/file.h" // for File + #define MYNAME "OZI" #define BADCHARS ",\r\n" #define DAYS_SINCE_1990 25569 -typedef struct { +struct ozi_fsdata { format_specific_data fs; int fgcolor; int bgcolor; -} ozi_fsdata; +}; +static struct { + gpsbabel::File* file{nullptr}; + QTextStream* stream{nullptr}; + QTextCodec* codec{nullptr}; +} ozi_file; -static gbfile* file_in, *file_out; static short_handle mkshort_handle; static route_head* trk_head; static route_head* rte_head; @@ -69,6 +102,7 @@ static char altunit; static char proxunit; static double alt_scale; static double prox_scale; +static char* opt_codec; static arglist_t ozi_args[] = { @@ -112,6 +146,10 @@ arglist_t ozi_args[] = { "proxunit", &proxunit_opt, "Unit used in proximity values", "miles", ARGTYPE_STRING, ARG_NOMINMAX, nullptr }, + { + "codec", &opt_codec, "codec to use for reading and writing strings (default windows-1252)", + "windows-1252", ARGTYPE_STRING, ARG_NOMINMAX, nullptr + }, ARG_TERMINATOR }; @@ -119,6 +157,41 @@ static gpsdata_type ozi_objective; static QString ozi_ofname; +static void +ozi_open_io(const QString& fname, QIODevice::OpenModeFlag mode) +{ + ozi_file.codec = QTextCodec::codecForName(opt_codec); + if (ozi_file.codec == nullptr) { + fatal(MYNAME ": Unsupported character set '%s'.\n", opt_codec); + } + + ozi_file.file = new gpsbabel::File(fname); + ozi_file.file->open(mode); + ozi_file.stream = new QTextStream(ozi_file.file); + ozi_file.stream->setCodec(ozi_file.codec); + + if (mode | QFile::WriteOnly) { + ozi_file.stream->setRealNumberNotation(QTextStream::FixedNotation); + } + + if (mode | QFile::ReadOnly) { + if (ozi_file.codec->mibEnum() == 106) { // UTF-8 + ozi_file.stream->setAutoDetectUnicode(true); + } + } +} + +static void +ozi_close_io() +{ + ozi_file.file->close(); + delete ozi_file.file; + ozi_file.file = nullptr; + delete ozi_file.stream; + ozi_file.stream = nullptr; + ozi_file.codec = nullptr; +} + static void ozi_copy_fsdata(ozi_fsdata** dest, ozi_fsdata* src) { @@ -151,15 +224,14 @@ ozi_alloc_fsdata() return fsdata; } -static void -ozi_get_time_str(const Waypoint* waypointp, char* buff, gbsize_t buffsz) +static QString +ozi_get_time_str(const Waypoint* waypointp) { if (waypointp->creation_time.isValid()) { double time = (waypt_time(waypointp) / SECONDS_PER_DAY) + DAYS_SINCE_1990; - snprintf(buff, buffsz, "%.7f", time); - } else { - *buff = '\0'; + return QString("%1").arg(time, 0, 'f', 7); } + return QString(""); } static void @@ -195,15 +267,15 @@ ozi_openfile(const QString& fname) */ if (fname == "-") { - if (! file_out) { - file_out = gbfopen(fname, "wb", MYNAME); + if (ozi_file.file == nullptr) { + ozi_open_io(fname, QFile::WriteOnly); } return; } QString buff; if ((track_out_count) && (ozi_objective == trkdata)) { - buff = QString("-%d").arg(track_out_count); + buff = QString("-%1").arg(track_out_count); } else { buff = QString(""); } @@ -219,30 +291,26 @@ ozi_openfile(const QString& fname) QString tmpname = QString("%1%2.%3").arg(sname, buff, ozi_extensions[ozi_objective]); /* re-open file_out with the new filename */ - if (file_out) { - gbfclose(file_out); - file_out = nullptr; + if (ozi_file.file != nullptr) { + ozi_close_io(); } - - file_out = gbfopen(tmpname, "wb", MYNAME); + + ozi_open_io(tmpname, QFile::WriteOnly); } static void ozi_track_hdr(const route_head* rte) { - static const char* ozi_trk_header = - "OziExplorer Track Point File Version 2.1\r\n" - "WGS 84\r\n" - "Altitude is in %s\r\n" - "Reserved 3\r\n" - "0,2,255,%s,0,0,2,8421376\r\n" - "0\r\n"; - if ((! pack_opt) || (track_out_count == 0)) { ozi_openfile(ozi_ofname); - gbfprintf(file_out, ozi_trk_header, - altunit == 'f' ? "Feet" : "Meters", - rte->rte_name.isEmpty() ? "ComplimentsOfGPSBabel" : CSTRc(rte->rte_name)); + *ozi_file.stream << "OziExplorer Track Point File Version 2.1\r\n" + << "WGS 84\r\n" + << "Altitude is in " << (altunit == 'f' ? "Feet" : "Meters") << "\r\n" + << "Reserved 3\r\n" + << "0,2,255," + << (rte->rte_name.isEmpty() ? "ComplimentsOfGPSBabel" : rte->rte_name) + << ",0,0,2,8421376\r\n" + << "0\r\n"; } track_out_count++; @@ -253,9 +321,8 @@ static void ozi_track_disp(const Waypoint* waypointp) { double alt; - char ozi_time[16]; - ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + QString ozi_time = ozi_get_time_str(waypointp); if (waypointp->altitude == unknown_alt) { alt = -777; @@ -263,22 +330,19 @@ ozi_track_disp(const Waypoint* waypointp) alt = waypointp->altitude * alt_scale; } - gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n", - waypointp->latitude, waypointp->longitude, new_track, - alt, ozi_time); + *ozi_file.stream << qSetRealNumberPrecision(6) << waypointp->latitude << ',' + << waypointp->longitude << ',' + << new_track << ',' + << qSetRealNumberPrecision(0) << alt << ',' + << ozi_time << ",,\r\n"; new_track = 0; } -static void -ozi_track_tlr(const route_head*) -{ -} - static void ozi_track_pr() { - track_disp_all(ozi_track_hdr, ozi_track_tlr, ozi_track_disp); + track_disp_all(ozi_track_hdr, nullptr, ozi_track_disp); } static void @@ -286,12 +350,10 @@ ozi_route_hdr(const route_head* rte) { /* prologue on 1st pass only */ if (route_out_count == 0) { - static const char* ozi_route_header = - "OziExplorer Route File Version 1.0\r\n" - "WGS 84\r\n" - "Reserved 1\r\n" - "Reserved 2\r\n"; - gbfprintf(file_out, ozi_route_header); + *ozi_file.stream << "OziExplorer Route File Version 1.0\r\n" + << "WGS 84\r\n" + << "Reserved 1\r\n" + << "Reserved 2\r\n"; } route_out_count++; @@ -309,20 +371,17 @@ ozi_route_hdr(const route_head* rte) * R, 1, ICP GALHETA,, 16711680 */ - gbfprintf(file_out, "R,%d,%s,%s,\r\n", - route_out_count, - CSTRc(rte->rte_name), - CSTRc(rte->rte_desc)); + *ozi_file.stream << "R," << route_out_count << ',' + << rte->rte_name << ',' + << rte->rte_desc << ",\r\n"; } static void ozi_route_disp(const Waypoint* waypointp) { - char ozi_time[16]; - route_wpt_count++; - ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + QString ozi_time = ozi_get_time_str(waypointp); /* double alt; @@ -353,26 +412,20 @@ ozi_route_disp(const Waypoint* waypointp) * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 */ - gbfprintf(file_out, "W,%d,,%d,%s,%.6f,%.6f,%s,0,1,3,0,65535,%s,0,0\r\n", - route_out_count, - route_wpt_count, - CSTR(waypointp->shortname), - waypointp->latitude, - waypointp->longitude, - ozi_time, - CSTR(waypointp->description)); + *ozi_file.stream << "W," << route_out_count << ",," + << route_wpt_count << ',' + << waypointp->shortname << ',' + << qSetRealNumberPrecision(6) << waypointp->latitude << ',' + << waypointp->longitude << ',' + << ozi_time << ",0,1,3,0,65535," + << waypointp->description << ",0,0\r\n"; } -static void -ozi_route_tlr(const route_head*) -{ -} - static void ozi_route_pr() { - route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp); + route_disp_all(ozi_route_hdr, nullptr, ozi_route_disp); } static void @@ -415,7 +468,7 @@ ozi_init_units(const int direction) /* 0 = in; 1 = out */ static void rd_init(const QString& fname) { - file_in = gbfopen(fname, "rb", MYNAME); + ozi_open_io(fname, QFile::ReadOnly); mkshort_handle = mkshort_new_handle(); ozi_init_units(0); @@ -424,8 +477,8 @@ rd_init(const QString& fname) static void rd_deinit() { - gbfclose(file_in); - file_in = nullptr; + ozi_close_io(); + mkshort_del_handle(&mkshort_handle); } @@ -464,18 +517,12 @@ wr_init(const QString& fname) ozi_init_units(1); parse_distance(proximityarg, &proximity, 1 / prox_scale, MYNAME); - - file_out = nullptr; } static void wr_deinit() { - if (file_out != nullptr) { - - gbfclose(file_out); - file_out = nullptr; - } + ozi_close_io(); ozi_ofname.clear(); mkshort_del_handle(&mkshort_handle); @@ -577,26 +624,24 @@ ozi_parse_waypt(int field, const QString& str, Waypoint* wpt_tmp, ozi_fsdata* fs } static void -ozi_parse_track(int field, char* str, Waypoint* wpt_tmp, char* trk_name) +ozi_parse_track(int field, const QString& str, Waypoint* wpt_tmp, char* trk_name) { - double alt; - - if (*str == '\0') { + if (str.isEmpty()) { return; } switch (field) { case 0: /* latitude */ - wpt_tmp->latitude = atof(str); + wpt_tmp->latitude = str.toDouble(); break; case 1: /* longitude */ - wpt_tmp->longitude = atof(str); + wpt_tmp->longitude = str.toDouble(); break; case 2: /* new track flag */ - if ((atoi(str) == 1) && (trk_head->rte_waypt_ct > 0)) { + if ((str.toInt() == 1) && (trk_head->rte_waypt_ct > 0)) { trk_head = route_head_alloc(); track_add_head(trk_head); if (trk_name) { @@ -604,15 +649,16 @@ ozi_parse_track(int field, char* str, Waypoint* wpt_tmp, char* trk_name) } } break; - case 3: + case 3: { /* altitude */ - alt = atof(str); + double alt = str.toDouble(); if (alt == -777) { wpt_tmp->altitude = unknown_alt; } else { wpt_tmp->altitude = alt * alt_scale; } break; + } case 4: /* DAYS since 1900 00:00:00 in days.days (5.5) */ ozi_set_time_str(str, wpt_tmp); @@ -623,9 +669,9 @@ ozi_parse_track(int field, char* str, Waypoint* wpt_tmp, char* trk_name) } static void -ozi_parse_routepoint(int field, char* str, Waypoint* wpt_tmp) +ozi_parse_routepoint(int field, const QString& str, Waypoint* wpt_tmp) { - if (*str == '\0') { + if (str.isEmpty()) { return; } @@ -648,11 +694,11 @@ ozi_parse_routepoint(int field, char* str, Waypoint* wpt_tmp) break; case 5: /* latitude */ - wpt_tmp->latitude = atof(str); + wpt_tmp->latitude = str.toDouble(); break; case 6: /* longitude */ - wpt_tmp->longitude = atof(str); + wpt_tmp->longitude = str.toDouble(); break; case 7: /* DAYS since 1900 00:00:00 in days.days (5.5) */ @@ -683,7 +729,7 @@ ozi_parse_routepoint(int field, char* str, Waypoint* wpt_tmp) } static void -ozi_parse_routeheader(int field, const QString& str, Waypoint*) +ozi_parse_routeheader(int field, const QString& str) { switch (field) { @@ -719,10 +765,12 @@ data_read() char* trk_name = nullptr; int linecount = 0; - while ((buff = gbfgetstr(file_in)), !buff.isNull()) { - if ((linecount++ == 0) && file_in->unicode) { - cet_convert_init(CET_CHARSET_UTF8, 1); + while (true) { + buff = ozi_file.stream->readLine(); + if (buff.isNull()) { + break; } + linecount++; /* * this is particularly nasty. use the first line of the file @@ -758,14 +806,9 @@ data_read() } } } else if ((linecount == 5) && (ozi_objective == trkdata)) { - int field = 0; - char* s = csv_lineparse(CSTR(buff), ",", "", linecount); - while (s) { - field ++; - if (field == 4) { - trk_head->rte_name = QString(s).trimmed(); - } - s = csv_lineparse(nullptr, ",", "", linecount); + const QStringList parts = buff.split(','); + if (parts.size() >= 4) { + trk_head->rte_name = parts.at(3).trimmed(); } } @@ -774,20 +817,19 @@ data_read() ozi_fsdata* fsdata = ozi_alloc_fsdata(); Waypoint* wpt_tmp = new Waypoint; - /* data delimited by commas, possibly enclosed in quotes. */ - char* orig_s = xstrdup(CSTR(buff)); - char* s = csv_lineparse(orig_s, ",", "", linecount); + /* data delimited by commas. */ + const QStringList parts = buff.split(','); int i = 0; bool header = false; - while (s) { + for (const auto& s : parts) { switch (ozi_objective) { case trkdata: ozi_parse_track(i, s, wpt_tmp, trk_name); break; case rtedata: if (buff[0] == 'R') { - ozi_parse_routeheader(i, QString(s), wpt_tmp); + ozi_parse_routeheader(i, QString(s)); header = true; } else { ozi_parse_routepoint(i, s, wpt_tmp); @@ -803,9 +845,7 @@ data_read() break; } i++; - s = csv_lineparse(nullptr, ",", "", linecount); } - xfree(orig_s); switch (ozi_objective) { case trkdata: @@ -861,7 +901,6 @@ ozi_waypt_pr(const Waypoint* wpt) { static int index = 0; double alt; - char ozi_time[16]; QString description; QString shortname; int faked_fsdata = 0; @@ -874,7 +913,7 @@ ozi_waypt_pr(const Waypoint* wpt) faked_fsdata = 1; } - ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time)); + QString ozi_time = ozi_get_time_str(wpt); if (wpt->altitude == unknown_alt) { alt = -777; @@ -911,18 +950,24 @@ ozi_waypt_pr(const Waypoint* wpt) icon = wpt->icon_descr.toInt(); } - gbfprintf(file_out, - "%d,%s,%.6f,%.6f,%s,%d,%d,%d,%d,%d,%s,%d,%d,", - index, CSTRc(shortname), wpt->latitude, wpt->longitude, ozi_time, icon, - 1, 3, fs->fgcolor, fs->bgcolor, CSTRc(description), 0, 0); + *ozi_file.stream << index << ',' + << shortname << ',' + << qSetRealNumberPrecision(6) << wpt->latitude << ',' + << wpt->longitude << ',' + << ozi_time << ',' + << icon << ',' + << "1,3," + << fs->fgcolor << ',' + << fs->bgcolor << ',' + << description << ",0,0,"; if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { - gbfprintf(file_out, "%.1f,", wpt->proximity * prox_scale); + *ozi_file.stream << qSetRealNumberPrecision(1) << wpt->proximity * prox_scale << ','; } else if (proximity > 0) { - gbfprintf(file_out,"%.1f,", proximity * prox_scale); + *ozi_file.stream << qSetRealNumberPrecision(1) << proximity * prox_scale << ','; } else { - gbfprintf(file_out,"%d,", 0); + *ozi_file.stream << "0,"; } - gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt, 6, 0, 17); + *ozi_file.stream << qSetRealNumberPrecision(0) << alt << ",6,0,17\r\n"; if (faked_fsdata) { xfree(fs); @@ -932,18 +977,14 @@ ozi_waypt_pr(const Waypoint* wpt) static void data_write() { - if (waypt_count()) { - static const char* ozi_wpt_header = - "OziExplorer Waypoint File Version 1.1\r\n" - "WGS 84\r\n" - "Reserved 2\r\n" - "Reserved 3\r\n"; - - track_out_count = route_out_count = 0; + track_out_count = route_out_count = 0; ozi_objective = wptdata; ozi_openfile(ozi_ofname); - gbfprintf(file_out, ozi_wpt_header); + *ozi_file.stream << "OziExplorer Waypoint File Version 1.1\r\n" + << "WGS 84\r\n" + << "Reserved 2\r\n" + << "Reserved 3\r\n"; waypt_disp_all(ozi_waypt_pr); } diff --git a/reference/route/ozi~rte.rte b/reference/route/ozi~rte.rte new file mode 100644 index 000000000..e557555c5 --- /dev/null +++ b/reference/route/ozi~rte.rte @@ -0,0 +1,10 @@ +OziExplorer Route File Version 1.0 +WGS 84 +Reserved 1 +Reserved 2 +R,1,1 COSTANERO JA,, +W,1,,1,MPCHIC,-34.445850,-58.523720,40507.8513987,0,1,3,0,65535,MARINA PUNTA CHICA,0,0 +W,1,,2,JA12,-34.447380,-58.507270,41344.8282040,0,1,3,0,65535,,0,0 +R,2,1 PCHI COLONIA,, +W,2,,1,COLONI,-34.467500,-57.854170,,0,1,3,0,65535,07-OCT-00 18:22,0,0 +W,2,,2,COLBO3W ,-34.477470,-57.861670,41154.0041088,0,1,3,0,65535,,0,0 diff --git a/reference/track/20070813_short.plt b/reference/track/20070813_short.plt new file mode 100644 index 000000000..68e1a492b --- /dev/null +++ b/reference/track/20070813_short.plt @@ -0,0 +1,50 @@ +OziExplorer Track Point File Version 2.1 +WGS 84 +Altitude is in Feet +Reserved 3 +0,2,255,Vézelay / Cuncy-lès-Varzy ,1,0,2,8421376,0 +2390 + 47.466222, 3.747318,0, 1258.8,39307.3279977, 13-août-07, 07:52:19 + 47.466150, 3.747233,0, 1236.5,39307.3281134, 13-août-07, 07:52:28 + 47.466130, 3.747113,0, 1243.4,39307.3282292, 13-août-07, 07:52:39 + 47.466078, 3.747023,0, 1237.5,39307.3282986, 13-août-07, 07:52:44 + 47.466020, 3.746888,0, 1221.4,39307.3283681, 13-août-07, 07:52:51 + 47.465943, 3.746815,0, 1203.7,39307.3284259, 13-août-07, 07:52:55 + 47.465872, 3.746727,0, 1177.2,39307.3284954, 13-août-07, 07:53:02 + 47.465902, 3.746598,0, 1168.3,39307.3285532, 13-août-07, 07:53:06 + 47.465900, 3.746465,0, 1159.1,39307.3286343, 13-août-07, 07:53:14 + 47.465792, 3.746433,0, 1157.8,39307.3287037, 13-août-07, 07:53:20 + 47.465713, 3.746388,0, 1154.5,39307.3287616, 13-août-07, 07:53:25 + 47.465695, 3.746242,0, 1160.4,39307.3288426, 13-août-07, 07:53:32 + 47.465697, 3.746097,0, 1160.1,39307.3289236, 13-août-07, 07:53:38 + 47.465717, 3.745948,0, 1169.3,39307.3289815, 13-août-07, 07:53:44 + 47.465715, 3.745807,0, 1189.0,39307.3290625, 13-août-07, 07:53:51 + 47.465640, 3.745703,0, 1205.0,39307.3291551, 13-août-07, 07:53:59 + 47.465575, 3.745608,0, 1203.1,39307.3292130, 13-août-07, 07:54:04 + 47.465488, 3.745547,0, 1197.2,39307.3292708, 13-août-07, 07:54:08 + 47.465447, 3.745437,0, 1180.8,39307.3293519, 13-août-07, 07:54:16 + 47.465353, 3.745390,0, 1157.5,39307.3294213, 13-août-07, 07:54:22 + 47.465298, 3.745282,0, 1141.4,39307.3295139, 13-août-07, 07:54:30 + 47.465250, 3.745155,0, 1100.1,39307.3296181, 13-août-07, 07:54:39 + 47.465157, 3.745133,0, 1101.4,39307.3296759, 13-août-07, 07:54:43 + 47.465018, 3.745113,0, 1094.5,39307.3297569, 13-août-07, 07:54:50 + 47.465010, 3.744965,0, 1101.7,39307.3298148, 13-août-07, 07:54:55 + 47.464992, 3.744823,0, 1114.2,39307.3299074, 13-août-07, 07:55:03 + 47.464955, 3.744658,0, 1124.3,39307.3300000, 13-août-07, 07:55:12 + 47.464885, 3.744563,0, 1130.6,39307.3300810, 13-août-07, 07:55:18 + 47.464778, 3.744497,0, 1117.1,39307.3301505, 13-août-07, 07:55:25 + 47.464710, 3.744412,0, 1109.2,39307.3302083, 13-août-07, 07:55:29 + 47.464635, 3.744317,0, 1110.9,39307.3302778, 13-août-07, 07:55:36 + 47.464547, 3.744233,0, 1109.6,39307.3303472, 13-août-07, 07:55:41 + 47.464475, 3.744142,0, 1112.8,39307.3304282, 13-août-07, 07:55:48 + 47.464405, 3.744057,0, 1101.7,39307.3304861, 13-août-07, 07:55:53 + 47.464342, 3.743965,0, 1098.1,39307.3305440, 13-août-07, 07:55:59 + 47.464313, 3.743808,0, 1094.8,39307.3306366, 13-août-07, 07:56:07 + 47.464233, 3.743725,0, 1077.7,39307.3307292, 13-août-07, 07:56:15 + 47.464173, 3.743628,0, 1066.6,39307.3308102, 13-août-07, 07:56:22 + 47.464102, 3.743548,0, 1064.9,39307.3308912, 13-août-07, 07:56:29 + 47.464015, 3.743477,0, 1049.9,39307.3309491, 13-août-07, 07:56:34 + 47.463935, 3.743393,0, 1045.3,39307.3310301, 13-août-07, 07:56:41 + 47.463860, 3.743303,0, 1063.3,39307.3311343, 13-août-07, 07:56:50 + 47.463847, 3.743163,0, 1062.7,39307.3312037, 13-août-07, 07:56:56 + 47.463833, 3.743018,0, 1072.5,39307.3312731, 13-août-07, 07:57:01 diff --git a/reference/track/20070813_short~plt.gpx b/reference/track/20070813_short~plt.gpx new file mode 100644 index 000000000..149e6060f --- /dev/null +++ b/reference/track/20070813_short~plt.gpx @@ -0,0 +1,186 @@ + + + + + + Vézelay / Cuncy-lès-Varzy + + + 383.682 + + + + 376.885 + + + + 378.988 + + + + 377.190 + + + + 372.283 + + + + 366.888 + + + + 358.811 + + + + 356.098 + + + + 353.294 + + + + 352.897 + + + + 351.892 + + + + 353.690 + + + + 353.598 + + + + 356.403 + + + + 362.407 + + + + 367.284 + + + + 366.705 + + + + 364.907 + + + + 359.908 + + + + 352.806 + + + + 347.899 + + + + 335.310 + + + + 335.707 + + + + 333.604 + + + + 335.798 + + + + 339.608 + + + + 342.687 + + + + 344.607 + + + + 340.492 + + + + 338.084 + + + + 338.602 + + + + 338.206 + + + + 339.181 + + + + 335.798 + + + + 334.701 + + + + 333.695 + + + + 328.483 + + + + 325.100 + + + + 324.582 + + + + 320.010 + + + + 318.607 + + + + 324.094 + + + + 323.911 + + + + 326.898 + + + + + diff --git a/reference/track/20070813_short~plt.plt b/reference/track/20070813_short~plt.plt new file mode 100644 index 000000000..e1d6d2a54 --- /dev/null +++ b/reference/track/20070813_short~plt.plt @@ -0,0 +1,50 @@ +OziExplorer Track Point File Version 2.1 +WGS 84 +Altitude is in Feet +Reserved 3 +0,2,255,Vézelay / Cuncy-lès-Varzy,0,0,2,8421376 +0 +47.466222,3.747318,1,1259,39307.3280015,, +47.466150,3.747233,0,1236,39307.3281056,, +47.466130,3.747113,0,1243,39307.3282330,, +47.466078,3.747023,0,1237,39307.3282908,, +47.466020,3.746888,0,1221,39307.3283719,, +47.465943,3.746815,0,1204,39307.3284181,, +47.465872,3.746727,0,1177,39307.3284992,, +47.465902,3.746598,0,1168,39307.3285455,, +47.465900,3.746465,0,1159,39307.3286381,, +47.465792,3.746433,0,1158,39307.3286959,, +47.465713,3.746388,0,1155,39307.3287654,, +47.465695,3.746242,0,1160,39307.3288464,, +47.465697,3.746097,0,1160,39307.3289158,, +47.465717,3.745948,0,1169,39307.3289853,, +47.465715,3.745807,0,1189,39307.3290663,, +47.465640,3.745703,0,1205,39307.3291589,, +47.465575,3.745608,0,1203,39307.3292168,, +47.465488,3.745547,0,1197,39307.3292631,, +47.465447,3.745437,0,1181,39307.3293557,, +47.465353,3.745390,0,1158,39307.3294251,, +47.465298,3.745282,0,1141,39307.3295177,, +47.465250,3.745155,0,1100,39307.3296219,, +47.465157,3.745133,0,1101,39307.3296682,, +47.465018,3.745113,0,1095,39307.3297492,, +47.465010,3.744965,0,1102,39307.3298071,, +47.464992,3.744823,0,1114,39307.3298997,, +47.464955,3.744658,0,1124,39307.3300038,, +47.464885,3.744563,0,1131,39307.3300733,, +47.464778,3.744497,0,1117,39307.3301543,, +47.464710,3.744412,0,1109,39307.3302006,, +47.464635,3.744317,0,1111,39307.3302816,, +47.464547,3.744233,0,1110,39307.3303395,, +47.464475,3.744142,0,1113,39307.3304205,, +47.464405,3.744057,0,1102,39307.3304784,, +47.464342,3.743965,0,1098,39307.3305478,, +47.464313,3.743808,0,1095,39307.3306404,, +47.464233,3.743725,0,1078,39307.3307330,, +47.464173,3.743628,0,1067,39307.3308140,, +47.464102,3.743548,0,1065,39307.3308835,, +47.464015,3.743477,0,1050,39307.3309529,, +47.463935,3.743393,0,1045,39307.3310339,, +47.463860,3.743303,0,1063,39307.3311381,, +47.463847,3.743163,0,1063,39307.3311960,, +47.463833,3.743018,0,1073,39307.3312654,, diff --git a/testo.d/ozi.test b/testo.d/ozi.test index b7774ecfa..986c58ff0 100644 --- a/testo.d/ozi.test +++ b/testo.d/ozi.test @@ -8,3 +8,12 @@ compare ${TMPDIR}/ozi.wpt ${REFERENCE} # Test Ozi routes. gpsbabel -i ozi -f ${REFERENCE}/route/ozi.rte -o gpx -F ${TMPDIR}/ozi~gpx.gpx compare ${TMPDIR}/ozi~gpx.gpx ${REFERENCE}/route/ +gpsbabel -i ozi -f ${REFERENCE}/route/ozi.rte -o ozi -F ${TMPDIR}/ozi~rte.rte +compare ${REFERENCE}/route/ozi~rte.rte ${TMPDIR}/ozi~rte.rte + +# Test Ozi tracks. +gpsbabel -i ozi -f ${REFERENCE}/track/20070813_short.plt -o gpx -F ${TMPDIR}/20070813_short~plt.gpx +compare ${REFERENCE}/track/20070813_short~plt.gpx ${TMPDIR}/20070813_short~plt.gpx +gpsbabel -i ozi -f ${REFERENCE}/track/20070813_short.plt -o ozi -F ${TMPDIR}/20070813_short~plt.plt +compare ${REFERENCE}/track/20070813_short~plt.plt ${TMPDIR}/20070813_short~plt.plt + diff --git a/xmldoc/formats/options/ozi-codec.xml b/xmldoc/formats/options/ozi-codec.xml new file mode 100644 index 000000000..b586abc7a --- /dev/null +++ b/xmldoc/formats/options/ozi-codec.xml @@ -0,0 +1,5 @@ + +This lets you override the default codec of 'windows-1252'. As an +input option the codec should correspond to the encoding of the input file. +As an output option it sets the encoding of the output file. +